#!/usr/bin/python

# Imports
import os
import sys
import getopt
import string
from pysqlite2 import dbapi2 as sqlite

# Define Globals
# Setup program name and version
program_name    = 'phlyBooks'
version_major   = 0
version_minor   = 1
version_state   = '-alpha'
version         = '%d.%d%s'                              % (version_major, version_minor, version_state)
version_string  = '%s %s (http://www.phly-project.org)'  % (program_name, version)

# Config dir
if os.name == 'nt':
    # Windows (SD-card)
    config_dir      = 'E:\\phly\\/%s'                        % program_name
else:
    config_dir      = '/home/phalax/.config/phly/%s'         % program_name


# Setup database
database        = '%s/%s.db'                             % (config_dir, program_name)

# Other globals
verbose         = False
fake            = False
action          = ''

# HELPER FUNCTIONS #####################################################
def usage_screen(view = 'help', error_message = ''):
    """Prints the help and about screens."""
    
    ############################
    # Define some defaults
    usage_text = ''
    exit_code = 0
    
    ############################
    # Setup the usage_text after view and error message
    if view == 'about':
        usage_text += 'About:\t%s is a Book organizer.\n' % program_name
        usage_text += '\tIts only made to be a simple script.\n'
        usage_text += '\tUse at your own risk!\n'
        usage_text += '\tFor more info check:\n'
        usage_text += '\thttp://sites.google.com/site/phlyproject/\n'
        usage_text += '\thttp://code.google.com/p/phlyproject/\n'
    elif view == 'help' or view == 'error':
        if error_message != '':
            usage_text += color_print(error_message, 'error') + '\n\n'
            exit_code = 2
        else:
            if view == 'error':
                usage_text += color_print('No message sent to usage_screen()', 'error')
                exit_code = 5
        usage_text += 'Usage:\t%s [options] <actions>\n' % program_name
        usage_text += 'Options:\n'
        usage_text += '\t-a\t\tPrint the about screen\n'
        usage_text += '\t-c\t\tPrint errorcode list\n'
        usage_text += '\t-V\t\tPrint version\n'
        usage_text += '\t-h\t\tPrint this help screen\n'
        usage_text += '\t-f\t\tFake run\n'
        usage_text += '\t-v\t\tSet verbose output\n'
        usage_text += 'Actions:\n'
        usage_text += '\t--add\t\tAdd book to library\n'
        usage_text += '\t--search\tSearch Google Books\n'
        usage_text += '\nExample: %s -v --search="Unix Programming\n' % program_name
    elif view == 'codes':
        usage_text += '2: User error\n'
        usage_text += '5: Syntax error\n'
    else:
        usage_text += color_print('Unknown "view" sent to usage_screen()', 'error')
        exit_code = 5
    ############################
    # Print and exit
    print usage_text
    sys.exit(exit_code)


def color_print(toColorize, colorizeOption = 'error'):
    """Colorize text using shell escape "\033" notation."""
        
    if os.name == 'posix':
        if colorizeOption == 'green':
            return '\033[0;32m%s\033[0;m'     % toColorize
        elif colorizeOption == 'blue':
            return '\033[0;34m%s\033[0;m'     % toColorize
        elif colorizeOption == 'black':
            return '\033[0;30m%s\033[0;m'     % toColorize
        elif colorizeOption == 'warning':
            return '\033[0;31m%s\033[0;m'     % toColorize
        elif colorizeOption == 'error':
            return '\033[0;31m%s\033[0;m'     % toColorize
        elif colorizeOption == 'number':
            if int(toColorize) != 0:
                return '\033[1;32m%s\033[1;m' % toColorize
            else:
                return '\033[1;31m%s\033[1;m' % toColorize
    else:
        return toColorize
########################################################################

# DATABASE FUNCTIONS ###################################################
def check_if_in_series(title):
    """Checks if book is in a series. (For example "For Dummies")
    Series are defined in the database."""
    cursor.execute('SELECT seriesID FROM series WHERE title LIKE ?', title)
    seriesID = cursor.fetchone()
    if not seriesID:
        ############################
        # Not in db
        return 0
    else:
        ############################
        # Exists in db
        return seriesID
        
def get_authorID(author):
    cursor.execute('SELECT authorID FROM authors WHERE name LIKE ?', author)
    authorID = cursor.fetchone()
    if not authorID:
        ############################
        # Not in db
        return 0
    else:
        ############################
        # Exists in db
        return authorID

def add_author_to_db(bookAuthor):
    cursor.execute('INSERT INTO authors VALUES(NULL,?)', bookAuthors)
    return cursor.lastrowid
    
def add_publisher_to_db(bookPublisher):
    cursor.execute('INSERT INTO publishers VALUES(NULL,?,NULL)', bookPublishers)
    return cursor.lastrowid

def add_Ebook_to_database(filename):
    ############################
    # Split path up nice
    filename = os.path.basename(filename)
    filename, ext = os.path.splitext(filename)
    bookTitle, bookAuthor, bookPublisher, bookISBN, bookCategory = google_book_search(filename, 1, False) # filename, results, print?
    
    ############################
    # Author
    if bookAuthor != 'Unknown':
        authorID = get_authorID(bookAuthor)
        if authorID == 0:
            authorID = add_author_to_db(bookAuthor)
    else:
        authorID = 1 # Unknown from Google
    
    ############################
    # Publisher
    if bookPublisher != 'Unknown':
        publisherID = get_publisherID(bookPublisher)
        if publisherID == 0:
            publisherID = add_publisher_to_db(bookPublisher)
    else:
        publisherID = 1 # Unknown from Google
    
    ############################
    # Series
    seriesID = get_seriesID(bookTitle)
    
    cursor.execute('INSERT INTO Ebooks VALUES (NULL,?,?,?,?,?,?,?,?)', bookTitle, publisherID, seriesID,)
    bookID = cursor.lastrowid
########################################################################

# Actions ##############################################################
def google_book_search(search_string, results = 3, feedback = True):
    """Searches Google Book for a string"""
    
    ############################
    # If search string is a filename(Must exist)
    # split file and path
    # split prefix and ext
    # overide search_string with prefix
    if os.path.isfile(search_string):
        filepath, filename        = os.path.split(search_string)
        search_string, extension  = os.path.splitext(filename)
    
    ############################
    # Do the search
    import feedparser
    search_string = search_string.replace(' ', '+')
    search_string = search_string.replace('.', '+')
    query = 'http://books.google.com/books/feeds/volumes?q=%s&max-results=%d' % (search_string, results)
    
    ############################
    # Print before parse.. There is a waiting time involved.
    if feedback == True:
        print 'Querying Google for: "%s"' % color_print(search_string,    'green')
        print '%s'                        % color_print('Please wait...', 'black')
        print '%s'                        % color_print('-'*60,           'black')
    
    ############################
    # Now parse
    books = feedparser.parse(query)
    for i in range(len(books.entries)):
        bookID         = books.entries[i]
        
        bookCategory   = bookID.get('subject'   , 'Unknown')
        bookTitle      = bookID.get('title'     , 'N/A')
        bookIdentifier = bookID.get('identifier', 'N/A')
        bookISBN       = bookIdentifier.replace('ISBN:','')
        bookAuthor     = bookID.get('creator'   , 'Unknown')
        bookPublisher  = bookID.get('publisher' , 'Unknown')
        if feedback == True:
            if i > 0:
                print '%s'        % color_print('-'*60,'black')
            print 'Result:    %d' % (i+1)
            print 'Title:     %s' % bookTitle
            print 'Author:    %s' % bookAuthor
            print 'Publisher: %s' % bookPublisher
            print 'ISBN:      %s' % bookISBN
            print 'Category:  %s' % bookCategory
        else:
            return (bookTitle, bookAuthor, bookPublisher, bookISBN, bookCategory)
########################################################################

def main():
    ############################
    # Define globals
    global action, fake, verbose

    ############################
    # Get arguments
    try:
        opts, args = getopt.getopt(sys.argv[1:], 'acVhfv', ['add=','search='])
    except getopt.GetoptError, err:
        usage_screen('error', str(err))

    # Now parse the options and arguments
    for o, a in opts:
        if   o in '-v':
            verbose = True
        elif o in '-f':
            fake = True
        elif o in '--add=':
            action = 'add'
            filename = a
        elif o in '--search=':
            if a != '':
                action = 'search'
                search_string = a
            else:
                usage_screen('error', 'No search string')
        elif o in '-h':
            usage_screen()
        elif o in '-a':
            usage_screen('about')

        elif o in '-c':
            usage_screen('codes')
        elif o == '-V':
            sys.exit()

    ############################
    # Connect to database
    connect         = sqlite.connect(database)
    cursor          = connect.cursor()
    
    ############################
    # Do the action asked for
    if action == 'add':
        add_Ebook_to_database(os.path.normpath(filename))
    elif action == 'search':
        google_book_search(search_string)
    else:
        usage_screen('error', 'No action specified!')


if __name__ == "__main__":
    ############################
    # Print program name and version etc
    print version_string, "\n"
    
    ############################
    # Go throught main
    main()
